package cn.yhp.chatgpt.data.domain.openai.service.rule.impl;

import cn.yhp.chatgpt.data.domain.openai.annotation.LogicStrategy;
import cn.yhp.chatgpt.data.domain.openai.model.aggregates.ChatProcessAggregate;
import cn.yhp.chatgpt.data.domain.openai.model.entity.RuleLogicEntity;
import cn.yhp.chatgpt.data.domain.openai.model.valobj.LogicCheckTypeVO;
import cn.yhp.chatgpt.data.domain.openai.service.rule.ILogicFilter;
import cn.yhp.chatgpt.data.domain.openai.service.rule.factory.DefaultLogicFactory;
import com.google.common.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 访问次数限制
 * @author yhp
 * @date 2024/2/7
 */
@Slf4j
@Component
@LogicStrategy(logicMode = DefaultLogicFactory.LogicModel.ACCESS_LIMIT)
public class AccessLimitFilter implements ILogicFilter {

    @Value("${app.config.limit-count:10}")
    private Integer limitCount;
    @Value("${app.config.white-list}")
    private String whiteListStr;

    // 某用户的调用频次限制
    @Resource
    private Cache<String,Integer> visitCache;

    @Override
    public RuleLogicEntity<ChatProcessAggregate> filter(ChatProcessAggregate chatProcess) throws Exception{
        // 1、白名单用户直接方形
        if (chatProcess.isWhiteList(whiteListStr)){
            return RuleLogicEntity.<ChatProcessAggregate>builder().type(LogicCheckTypeVO.SUCCESS).data(chatProcess).build();
        }
        // 2、访问次数限制
        String openid = chatProcess.getOpenid();
        Integer visitCount = visitCache.get(openid, () -> 0);
        // 没到次数限制，返回ok
        if (visitCount < limitCount){
            // 次数+1
            visitCache.put(openid,visitCount+1);
            return RuleLogicEntity.<ChatProcessAggregate>builder()
                    .type(LogicCheckTypeVO.SUCCESS).data(chatProcess).build();
        }
        // 3、次数用尽直接返回
        return RuleLogicEntity.<ChatProcessAggregate>builder()
                .type(LogicCheckTypeVO.REFUSE)
                .info("您今日的免费"+visitCount+"次，已耗尽。")
                .data(chatProcess).build();
    }
}
